package com.aloda.service.impl;

import com.aloda.constant.BookConstant;
import com.aloda.constant.ExceptionConstant;
import com.aloda.constant.UserConstant;
import com.aloda.exception.AuthException;
import com.aloda.exception.BaseException;
import com.aloda.mapper.BookMapper;
import com.aloda.mapper.RecordMapper;
import com.aloda.pojo.dto.*;
import com.aloda.pojo.entity.Book;
import com.aloda.pojo.entity.Record;
import com.aloda.result.PageResult;
import com.aloda.service.BookService;
import com.aloda.utils.UserHolder;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookMapper bookMapper;

    @Autowired
    private RecordMapper recordMapper;

    /**
     * 分页查询图书
     *
     * @param bookPageDTO
     * @return
     */
    @Override
    public PageResult<Book> getBookPage(BookPageDTO bookPageDTO) {
        PageHelper.startPage(bookPageDTO.getCurrentPage(), bookPageDTO.getPageSize());
        Page<Book> page = bookMapper.selectPage(bookPageDTO);
        return new PageResult<>(page.getTotal(), page.getResult());
    }

    /**
     * 新增图书
     *
     * @param bookAddDTO
     */
    @Override
    public void addBook(BookAddDTO bookAddDTO) {
        // 权限校验
        UserSafetyDTO user = UserHolder.getUser();
        if(!UserConstant.USER_ADMIN.equals(user.getRole())) {
            throw new AuthException(ExceptionConstant.AUTH_EXCEPTION);
        }
        // TODO: 可以增加格式校验
        Book book = new Book();
        BeanUtils.copyProperties(bookAddDTO, book);
        book.setUploadTime(LocalDate.now().toString());
        bookMapper.insert(book);
    }

    /**
     * 根据id查询图书
     *
     * @param id
     * @return
     */
    @Override
    public Book getBookById(Integer id) {
        return bookMapper.selectById(id);
    }

    /**
     * 编辑图书
     *
     * @param bookEditDTO
     */
    @Override
    public void editBook(BookEditDTO bookEditDTO) {
        // 权限校验
        UserSafetyDTO user = UserHolder.getUser();
        if(!UserConstant.USER_ADMIN.equals(user.getRole())) {
            throw new AuthException(ExceptionConstant.AUTH_EXCEPTION);
        }
        // TODO: 可以增加格式校验

        Book book = bookMapper.selectById(bookEditDTO.getId());
        // 只能编辑可借阅和已下架的书
        if (!BookConstant.STATUS_NORMAL.equals(book.getStatus())
                && !BookConstant.STATUS_SOLD_OUT.equals(book.getStatus())) {
            throw new BaseException(ExceptionConstant.EDIT_ERROR);
        }
        BeanUtils.copyProperties(bookEditDTO, book);
        bookMapper.update(book);
    }

    /**
     * 借阅图书
     *
     * @param bookBorrowDTO 图书借阅dto
     */
    @Override
    public void borrowBook(BookBorrowDTO bookBorrowDTO) {
        // 1.根据id获取图书信息
        Book book = bookMapper.selectById(bookBorrowDTO.getId());
        // 2.判断当前图书能否借阅
        if (!BookConstant.STATUS_NORMAL.equals(book.getStatus())) {
            throw new BaseException(ExceptionConstant.BORROW_ERROR);
        }
        // 3.获取当前借阅的用户
        UserSafetyDTO user = UserHolder.getUser();
        // 4.写入借阅信息
        book.setBorrower(user.getName());
        book.setBorrowerId(user.getId());
        book.setBorrowTime(LocalDate.now().toString());
        book.setReturnTime(bookBorrowDTO.getReturnTime());
        book.setStatus(BookConstant.STATUS_BORROWING);
        // 5.更新当前图书信息
        bookMapper.update(book);
    }

    /**
     * 获取当前借阅图书分页
     *
     * @param bookPageDTO
     * @return
     */
    @Override
    public PageResult<Book> getCurrentBorrowBookPage(BookPageDTO bookPageDTO) {
        // 获取当前登录用户
        UserSafetyDTO user = UserHolder.getUser();
        BookQueryDTO bookQueryDTO = new BookQueryDTO();
        BeanUtils.copyProperties(bookPageDTO,bookQueryDTO);
        bookQueryDTO.setUserId(user.getId());
        // 开始分页
        PageHelper.startPage(bookPageDTO.getCurrentPage(), bookPageDTO.getPageSize());
        // 如果当前登录用户是普通用户，直接查找借阅书籍
        Page page = new Page<>();
        if (UserConstant.USER_USER.equals(user.getRole())) {
            page = bookMapper.selectCurrentBorrowBookPage(bookQueryDTO);
        }
        // 如果当前用户为管理员，查找其借阅书籍和所有归还中的书籍
        if (UserConstant.USER_ADMIN.equals(user.getRole())) {
            page = bookMapper.selectAdminBookPage(bookQueryDTO);
        }
        return new PageResult<>(page.getTotal(),page.getResult());
    }

    /**
     * 归还图书
     *
     * @param id
     */
    @Override
    public void returnBook(Integer id) {
        // 根据id获取对应的图书
        Book book = bookMapper.selectById(id);
        // 只能归还已借阅的图书
        if(!BookConstant.STATUS_BORROWING.equals(book.getStatus())) {
            throw new BaseException(ExceptionConstant.RETURN_ERROR);
        }
        // 获取归还用户id
        Integer userId = UserHolder.getUser().getId();
        // 检查还书用户是否正确
        if(!userId.equals(book.getBorrowerId())) {
            throw new AuthException(ExceptionConstant.AUTH_EXCEPTION);
        }
        // 设置图书状态为归还中
        book.setStatus(BookConstant.STATUS_RETURN);
        // 更新数据
        bookMapper.update(book);
    }

    /**
     * 归还确认
     *
     * @param id
     */
    @Override
    @Transactional
    public void returnConfirm(Integer id) {
        // 根据id查找对应的图书
        Book book = bookMapper.selectById(id);
        // 检验是否为归还中图书
        if(!BookConstant.STATUS_RETURN.equals(book.getStatus())) {
            throw new BaseException(ExceptionConstant.CONFIRM_ERROR);
        }
        // 校验权限
        UserSafetyDTO user = UserHolder.getUser();
        if(!UserConstant.USER_ADMIN.equals(user.getRole())) {
            throw new AuthException(ExceptionConstant.AUTH_EXCEPTION);
        }
        // 设置借阅记录
        Record record = new Record();
        record.setBookname(book.getName());
        record.setBookisbn(book.getIsbn());
        record.setBorrower(book.getBorrower());
        record.setBorrowTime(book.getBorrowTime());
        record.setRemandTime(LocalDate.now().toString());
        // 将图书状态设置为可借阅
        book.setStatus(BookConstant.STATUS_NORMAL);
        // 清除该图书借阅记录
        book.setBorrowerId(null);
        book.setBorrower("");
        book.setBorrowTime("");
        book.setReturnTime("");
        // 更新数据
        recordMapper.insert(record);
        bookMapper.update(book);
    }

    /**
     * 获取推荐图书
     *
     * @return
     */
    @Override
    public List<Book> getRecommendBook() {
        return bookMapper.selectNewBookByNum(BookConstant.RECOMMEND_BOOK_NUMS);
    }
}
